from random import randint
import pyautogui as pauto
import os
from time import sleep
import cv2
import numpy as np
import copy
import threading
import pyperclip as pclip



# 获取位置，辅助写代码
def getlocation():
    try:
        while True:
            print("按下Ctrl + C 结束程序")
            # pag.position()返回鼠标的坐标
            x, y = pauto.position()
            posStr = "当前鼠标位置:" + str(x).rjust(4) + ',' + str(y).rjust(4)
            # 打印当前鼠标位置坐标
            print(posStr)
            sleep(1)
            # 清除屏幕
            # os.system('cls')
    # 捕获异常 KeyboardInterrupt:用户中断执行(通常是输入^C)
    except KeyboardInterrupt:
        print('已退出')

#点击函数，加个时延
def myclick(x,y,isleft = True):
    if isleft:
        pauto.click(x,y,button='left')
    else:
        pauto.click(x,y,button='right')
    sleep(0.1)

# Ctrl组合键
def CtrlClick(key):
    pauto.keyDown('ctrl')
    pauto.press(key)
    pauto.keyUp('ctrl')
    sleep(0.1)

"""
抖音辅助下载器
网页点击博主首页
右变打开开发控制台1300px位置 network,过滤media
点开博主第一个视频
do while
复制过滤到的Link address
打开新标签页，粘贴连接，点三个点下载视频，关闭标签页
清空控制台过滤结果，左边下滑下一个视频
end
循环
"""
    
def douyinDownloader(num):
    # 链接保存器
    linklist = []
    for i in range(num):
        # 复制连接
        myclick(2620,636)
        myclick(2620,636,False)
        sleep(0.1)
        myclick(2947,840)
        myclick(3458,839)
        # 保存连接
        data = pclip.paste()
        linklist.append(data)
        # 清空抓包
        myclick(2690, 218)
        # 划到下一个视频
        pauto.moveTo(1274,1023)
        pauto.scroll(-100)
        sleep(randint(3,6))
    # 卡住，等待输入后开始
    print('输入任意值5s后开始下载：',end='')
    input()
    sleep(5)
    for link in linklist:
        pclip.copy(link)
        # 粘贴链接并进入
        myclick(970,103)
        CtrlClick("v")
        pauto.press("enter")
        sleep(randint(3,6))
        # 进入全屏
        pauto.click(1900,1000,clicks=2)
        sleep(0.5)
        # 保存视频
        pauto.moveTo(3744,2047)
        sleep(0.5)
        myclick(3744,2047)
        sleep(0.5)
        myclick(3540,1872)
        #关闭全屏和提示栏
        pauto.click(1900,1000,clicks=2)
        sleep(0.5)
        myclick(3800,2021)


    """
    分割函数：通过截图对比两帧的相似度，判定是否要切割，配合达芬奇使用
    1.截图1
    2.按下一键
    3.截图2
    4.对比，相似则继续按下一键，截图2代替截图1
    5.不相似则按上一键，点击切割按钮，按下一键，截图2代替截图1
    """

def pHash(img):
    # 感知哈希算法
    # 缩放32*32
    img = cv2.resize(img, (32, 32))   # , interpolation=cv2.INTER_CUBIC
 
    # 转换为灰度图
    gray = img
    # gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型，再进行dct变换
    dct = cv2.dct(np.float32(gray))
    # opencv实现的掩码操作
    dct_roi = dct[0:8, 0:8]
 
    hash = []
    avreage = np.mean(dct_roi)
    for i in range(dct_roi.shape[0]):
        for j in range(dct_roi.shape[1]):
            if dct_roi[i, j] > avreage:
                hash.append('1')
            else:
                hash.append('0')
    return ''.join(hash)

def aHash(img):
    # 均值哈希算法
    # 缩放为8*8
    img = cv2.resize(img, (8, 8))
    # 转换为灰度图
    gray = img
    #gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # s为像素和初值为0，hash_str为hash值初值为''
    s = 0
    hash_str = ''
    # 遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s = s+gray[i, j]
    # 求平均灰度
    avg = s/64
    # 灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if gray[i, j] > avg:
                hash_str = hash_str+'1'
            else:
                hash_str = hash_str+'0'
    return hash_str
                

def cmpHash(hash1, hash2):
    # Hash值对比
    # 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定，但是比较的时候必须是相同的顺序。
    # 对比两幅图的指纹，计算汉明距离，即两个64位的hash值有多少是不一样的，不同的位数越小，图片越相似
    # 汉明距离：一组二进制数据变成另一组数据所需要的步骤，可以衡量两图的差异，汉明距离越小，则相似度越高。汉明距离为0，即两张图片完全一样
    n = 0
    length = len(hash1)
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(length):
        # 不相等则n计数+1，n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return (length-n)/length

# 定时保存器
def timeSave(t = 600):
    while(True):
        sleep(t)
        CtrlClick('s')
        print('定时保存')

def splitVideo():
    # 取灰度图
    img1 = pauto.screenshot(region=(2564, 305, 515,908))
    img1 = cv2.cvtColor(np.asarray(img1),cv2.COLOR_BGR2GRAY)
    height=len(img1)
    width=len(img1[0])
    # 描边图,截取中心图
    # edges1 = cv2.Canny(img1[int(height/4):int(height/4*3),int(width/4):int(width/4*3)],32,128,apertureSize=5)
    edges1 = cv2.Canny(img1,50,128,apertureSize=5)
    # 二值图，截图中心图
    ret,im_fixed1=cv2.threshold(img1[int(height/4):int(height/4*3),int(width/4):int(width/4*3)],100,255,cv2.THRESH_BINARY)
    # 计算图1三种哈希
    hash11 = pHash(edges1)
    hash21 = aHash(img1)
    hash31 = pHash(im_fixed1)
    # 起一个定时保存线程
    time_save = threading.Thread(target=timeSave)
    time_save.setDaemon(True)
    time_save.start()
    # 判断是不是到结束
    is_end = False
    while(True):
        # 下一帧
        pauto.press('right')
        # 截图2
        img2 = pauto.screenshot(region=(2564, 305, 515,908))
        img2 = cv2.cvtColor(np.asarray(img2),cv2.COLOR_BGR2GRAY)
        height=len(img2)
        width=len(img2[0])
        # 获取描边图和二值图
        # edges2 = cv2.Canny(img2[int(height/4):int(height/4*3),int(width/4):int(width/4*3)],32,128,apertureSize=5)
        edges2 = cv2.Canny(img2,50,128,apertureSize=5)
        ret,im_fixed2=cv2.threshold(img2[int(height/4):int(height/4*3),int(width/4):int(width/4*3)],100,255,cv2.THRESH_BINARY)
        # 计算图2三种哈希
        hash12 = pHash(edges2)
        hash22 = aHash(img2)
        hash32 = pHash(im_fixed2)
        # 计算图1和图2的汉明距离
        similarity1 = cmpHash(hash11,hash12)
        similarity2 = cmpHash(hash21,hash22)
        similarity3 = cmpHash(hash31,hash32)
        # 图2参数复制到图1
        hash11 = copy.copy(hash12)
        hash21 = copy.copy(hash22)
        hash31 = copy.copy(hash32)
        # 结束判断
        if int(hash12)==int(hash22)==0 and is_end:
            break
        elif int(hash22)!=0 and is_end:
            is_end = False
            continue
        # print(f'裁剪相似度 p {similarity1} \t a {similarity2} \t a2 {similarity3}')
        # continue
        # 开始投票
        vote = 0
        if similarity1 < 0.6:
            vote += 1
        if similarity2 < 0.7:
            vote += 1
        if similarity3 < 0.6:
            vote += 1
        if vote >=2:
            myclick(150,1358)
            print(f'裁剪相似度 p {similarity1} \t a {similarity2} \t a2 {similarity3}')
            # 结束
            if int(hash12)==int(hash22)==0:
                is_end = True
                print('结束标志位')
                for i in range(20):
                    pauto.press('right')
                continue
                
            
def splitVideoByRGB():
    # 取灰度图
    img1 = pauto.screenshot(region=(2156,263, 1300,970))
    img1= cv2.cvtColor(np.asarray(img1),cv2.COLOR_RGB2BGR)
    img1_g,img1_b,img1_r = cv2.split(img1)
    phash1_g = aHash(img1_g)
    phash1_b = aHash(img1_b)
    phash1_r = aHash(img1_r)
    phash1_gbr = phash1_g+phash1_b+phash1_r
    # 起一个定时保存线程
    time_save = threading.Thread(target=timeSave)
    time_save.setDaemon(True)
    time_save.start()
    # 判断是不是到结束
    is_end = False
    while(True):
        # 下一帧
        pauto.press('right')
        # 截图2
        img2 = pauto.screenshot(region=(2156,263, 1300,970))
        img2 = cv2.cvtColor(np.asarray(img2),cv2.COLOR_RGB2BGR)
        img2_g,img2_b,img2_r = cv2.split(img2)
        phash2_g = aHash(img2_g)
        phash2_b = aHash(img2_b)
        phash2_r = aHash(img2_r)
        phash2_gbr = phash2_g+phash2_b+phash2_r
        # 计算图1和图2的汉明距离
        similarity1 = cmpHash(phash1_gbr,phash2_gbr)
        # 图2参数复制到图1
        phash1_gbr = copy.copy(phash2_gbr)
        # 结束判断
        if int(phash2_gbr)==0 and is_end:
            CtrlClick('s')
            print('保存结束')
            break
        elif int(phash2_gbr)!=0 and is_end:
            is_end = False
            continue
        if similarity1 < 0.75:
            myclick(150,1358)
            print(f'裁剪相似度 p {similarity1}')
            # 结束
        if int(phash2_gbr)==0:
            is_end = True
            print('结束标志位')
            for i in range(20):
                pauto.press('right')
            continue
    
def main():
    sleep(5)
    splitVideoByRGB()
    
#main()